home *** CD-ROM | disk | FTP | other *** search
/ Disc to the Future 2 / Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin / UNIX / C / INDENT / PRCOMENT.C < prev    next >
C/C++ Source or Header  |  1989-08-31  |  13KB  |  415 lines

  1. /*
  2.  * Copyright (c) 1985 Sun Microsystems, Inc.
  3.  * Copyright (c) 1980 The Regents of the University of California.
  4.  * Copyright (c) 1976 Board of Trustees of the University of Illinois.
  5.  * All rights reserved.
  6.  *
  7.  * Redistribution and use in source and binary forms are permitted
  8.  * provided that the above copyright notice and this paragraph are
  9.  * duplicated in all such forms and that any documentation,
  10.  * advertising materials, and other materials related to such
  11.  * distribution and use acknowledge that the software was developed
  12.  * by the University of California, Berkeley, the University of Illinois,
  13.  * Urbana, and Sun Microsystems, Inc.  The name of either University
  14.  * or Sun Microsystems may not be used to endorse or promote products
  15.  * derived from this software without specific prior written permission.
  16.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  17.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  18.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  19.  */
  20.  
  21. #ifndef lint
  22. static char sccsid[] = "@(#)pr_comment.c    5.9 (Berkeley) 9/15/88";
  23. #endif /* not lint */
  24.  
  25. /*
  26.  * NAME:
  27.  *    pr_comment
  28.  *
  29.  * FUNCTION:
  30.  *    This routine takes care of scanning and printing comments.
  31.  *
  32.  * ALGORITHM:
  33.  *    1) Decide where the comment should be aligned, and if lines should
  34.  *       be broken.
  35.  *    2) If lines should not be broken and filled, just copy up to end of
  36.  *       comment.
  37.  *    3) If lines should be filled, then scan thru input_buffer copying
  38.  *       characters to com_buf.  Remember where the last blank, tab, or
  39.  *       newline was.  When line is filled, print up to last blank and
  40.  *       continue copying.
  41.  *
  42.  * HISTORY:
  43.  *    November 1976    D A Willcox of CAC    Initial coding
  44.  *    12/6/76        D A Willcox of CAC    Modification to handle
  45.  *                        UNIX-style comments
  46.  *
  47.  */
  48.  
  49. /*
  50.  * this routine processes comments.  It makes an attempt to keep comments from
  51.  * going over the max line length.  If a line is too long, it moves everything
  52.  * from the last blank to the next comment line.  Blanks and tabs from the
  53.  * beginning of the input line are removed
  54.  */
  55.  
  56.  
  57. #include "indent_globs.h"
  58.  
  59.  
  60. pr_comment()
  61. {
  62.     int         now_col;    /* column we are in now */
  63.     int         adj_max_col;    /* Adjusted max_col for when we decide to
  64.                  * spill comments over the right margin */
  65.     char       *last_bl;    /* points to the last blank in the output
  66.                  * buffer */
  67.     char       *t_ptr;        /* used for moving string */
  68.     int         unix_comment;    /* tri-state variable used to decide if it is
  69.                  * a unix-style comment. 0 means only blanks
  70.                  * since /*, 1 means regular style comment, 2
  71.                  * means unix style comment */
  72.     int         break_delim = comment_delimiter_on_blankline;
  73.     int         l_just_saw_decl = parser_state_tos->just_saw_decl;
  74.     /*
  75.      * int         parser_state_tos->last_nl = 0;    /* true iff the last significant thing
  76.      * weve seen is a newline
  77.      */
  78.     int         one_liner = 1;    /* true iff this comment is a one-liner */
  79.     adj_max_col = max_col;
  80.     parser_state_tos->just_saw_decl = 0;
  81.     last_bl = 0;        /* no blanks found so far */
  82.     parser_state_tos->box_com = false;        /* at first, assume that we are not in
  83.                      * a boxed comment or some other
  84.                      * comment that should not be touched */
  85.     ++parser_state_tos->out_coms;        /* keep track of number of comments */
  86.     unix_comment = 1;        /* set flag to let us figure out if there is a
  87.                  * unix-style comment ** DISABLED: use 0 to
  88.                  * reenable this hack! */
  89.  
  90.     /* Figure where to align and how to treat the comment */
  91.  
  92.     if (parser_state_tos->col_1 && !format_col1_comments) {    /* if comment starts in column
  93.                          * 1 it should not be touched */
  94.     parser_state_tos->box_com = true;
  95.     parser_state_tos->com_col = 1;
  96.     }
  97.     else {
  98.     if (*buf_ptr == '-' || *buf_ptr == '*' || !format_comments) {
  99.         parser_state_tos->box_com = true;    /* a comment with a '-' or '*' immediately
  100.                  * after the /* is assumed to be a boxed
  101.                  * comment */
  102.         break_delim = 0;
  103.     }
  104.     if ( /* parser_state_tos->bl_line && */ (s_lab == e_lab) && (s_code == e_code)) {
  105.         /* klg: check only if this line is blank */
  106.         /*
  107.          * If this (*and previous lines are*) blank, dont put comment way
  108.          * out at left
  109.          */
  110.         parser_state_tos->com_col = (parser_state_tos->ind_level - unindent_displace) + 1;
  111.         adj_max_col = block_comment_max_col;
  112.         if (parser_state_tos->com_col <= 1)
  113.         parser_state_tos->com_col = 1 + !format_col1_comments;
  114.     }
  115.     else {
  116.         register    target_col;
  117.         break_delim = 0;
  118.         if (s_code != e_code)
  119.         target_col = count_spaces(compute_code_target(), s_code);
  120.         else {
  121.         target_col = 1;
  122.         if (s_lab != e_lab)
  123.             target_col = count_spaces(compute_label_target(), s_lab);
  124.         }
  125.         parser_state_tos->com_col = parser_state_tos->decl_on_line || parser_state_tos->ind_level == 0 ? decl_com_ind : com_ind;
  126.         /* If we are already past the position for the comment,
  127.            put it at the next tab stop.  */
  128.         if (parser_state_tos->com_col < target_col)
  129.         parser_state_tos->com_col = ((target_col + 7) & ~7) + 1;
  130.         if (else_or_endif)
  131.           {
  132.         parser_state_tos->com_col = else_endif_col;
  133.         else_or_endif = false;
  134.         /* We want the comment to appear one space after the #else
  135.            or #endif.  */
  136.         if (parser_state_tos->com_col < target_col)
  137.           parser_state_tos->com_col = target_col + 1;
  138.           }
  139.         if (parser_state_tos->com_col + 24 > adj_max_col)
  140.         adj_max_col = parser_state_tos->com_col + 24;
  141.     }
  142.     }
  143.     if (parser_state_tos->box_com) {
  144.     buf_ptr[-2] = 0;
  145.     parser_state_tos->n_comment_delta = 1 - count_spaces(1, cur_line);
  146.     buf_ptr[-2] = '/';
  147.     }
  148.     else {
  149.     parser_state_tos->n_comment_delta = 0;
  150.     while (*buf_ptr == ' ' || *buf_ptr == '\t')
  151.         buf_ptr++;
  152.     }
  153.     parser_state_tos->comment_delta = 0;
  154.     *e_com++ = '/';        /* put '/*' into buffer */
  155.     *e_com++ = '*';
  156.     if (*buf_ptr != ' ' && !parser_state_tos->box_com)
  157.     *e_com++ = ' ';
  158.  
  159.     *e_com = '\0';
  160.     if (troff) {
  161.     now_col = 1;
  162.     adj_max_col = 80;
  163.     }
  164.     else
  165.     now_col = count_spaces(parser_state_tos->com_col, s_com);    /* figure what column we
  166.                              * would be in if we
  167.                              * printed the comment
  168.                              * now */
  169.  
  170.     /* Start to copy the comment */
  171.  
  172.     while (1) {            /* this loop will go until the comment is
  173.                  * copied */
  174.     if (*buf_ptr > 040 && *buf_ptr != '*')
  175.         parser_state_tos->last_nl = 0;
  176.     check_com_size;
  177.     switch (*buf_ptr) {    /* this checks for various spcl cases */
  178.     case 014:        /* check for a form feed */
  179.         if (!parser_state_tos->box_com) {    /* in a text comment, break the line here */
  180.         parser_state_tos->use_ff = true;
  181.         /* fix so dump_line uses a form feed */
  182.         dump_line();
  183.         last_bl = 0;
  184.         *e_com++ = ' ';
  185.         *e_com++ = '*';
  186.         *e_com++ = ' ';
  187.         while (*++buf_ptr == ' ' || *buf_ptr == '\t');
  188.         }
  189.         else {
  190.         if (++buf_ptr >= buf_end)
  191.             fill_buffer();
  192.         *e_com++ = 014;
  193.         }
  194.         break;
  195.  
  196.     case '\n':
  197.         if (had_eof) {    /* check for unexpected eof */
  198.         printf("Unterminated comment\n");
  199.         *e_com = '\0';
  200.         dump_line();
  201.         return;
  202.         }
  203.         one_liner = 0;
  204.         if (parser_state_tos->box_com || parser_state_tos->last_nl) {    /* if this is a boxed comment,
  205.                          * we dont ignore the newline */
  206.         if (s_com == e_com) {
  207.             *e_com++ = ' ';
  208.             *e_com++ = ' ';
  209.         }
  210.         *e_com = '\0';
  211.         if (!parser_state_tos->box_com && e_com - s_com > 3) {
  212.             if (break_delim == 1 && s_com[0] == '/'
  213.                 && s_com[1] == '*' && s_com[2] == ' ') {
  214.             char       *t = e_com;
  215.             break_delim = 2;
  216.             e_com = s_com + 2;
  217.             *e_com = 0;
  218.             if (blanklines_before_blockcomments)
  219.                 prefix_blankline_requested = 1;
  220.             dump_line();
  221.             e_com = t;
  222.             s_com[0] = s_com[1] = s_com[2] = ' ';
  223.             }
  224.             dump_line();
  225.             check_com_size;
  226.             *e_com++ = ' ';
  227.             *e_com++ = ' ';
  228.         }
  229.         dump_line();
  230.         now_col = parser_state_tos->com_col;
  231.         }
  232.         else {
  233.         parser_state_tos->last_nl = 1;
  234.         if (unix_comment != 1) {    /* we not are in unix_style
  235.                          * comment */
  236.             if (unix_comment == 0 && s_code == e_code) {
  237.             /*
  238.              * if it is a UNIX-style comment, ignore the
  239.              * requirement that previous line be blank for
  240.              * unindention
  241.              */
  242.             parser_state_tos->com_col = ((parser_state_tos->ind_level - unindent_displace)
  243.                       + ind_size);
  244.             if (parser_state_tos->com_col <= 1)
  245.                 parser_state_tos->com_col = 2;
  246.             }
  247.             unix_comment = 2;    /* permanently remember that we are in
  248.                      * this type of comment */
  249.             dump_line();
  250.             ++line_no;
  251.             now_col = parser_state_tos->com_col;
  252.             *e_com++ = ' ';
  253.             /*
  254.              * fix so that the star at the start of the line will line
  255.              * up
  256.              */
  257.             do        /* flush leading white space */
  258.             if (++buf_ptr >= buf_end)
  259.                 fill_buffer();
  260.             while (*buf_ptr == ' ' || *buf_ptr == '\t');
  261.             break;
  262.         }
  263.         if (*(e_com - 1) == ' ' || *(e_com - 1) == '\t')
  264.             last_bl = e_com - 1;
  265.         /*
  266.          * if there was a space at the end of the last line, remember
  267.          * where it was
  268.          */
  269.         else {        /* otherwise, insert one */
  270.             last_bl = e_com;
  271.             check_com_size;
  272.             *e_com++ = ' ';
  273.             ++now_col;
  274.         }
  275.         }
  276.         ++line_no;        /* keep track of input line number */
  277.         if (!parser_state_tos->box_com) {
  278.         int         nstar = 1;
  279.         do {        /* flush any blanks and/or tabs at start of
  280.                  * next line */
  281.             if (++buf_ptr >= buf_end)
  282.             fill_buffer();
  283.             if (*buf_ptr == '*' && --nstar >= 0) {
  284.             if (++buf_ptr >= buf_end)
  285.                 fill_buffer();
  286.             if (*buf_ptr == '/')
  287.                 goto end_of_comment;
  288.             }
  289.         } while (*buf_ptr == ' ' || *buf_ptr == '\t');
  290.         }
  291.         else if (++buf_ptr >= buf_end)
  292.         fill_buffer();
  293.         break;        /* end of case for newline */
  294.  
  295.     case '*':        /* must check for possibility of being at end
  296.                  * of comment */
  297.         if (++buf_ptr >= buf_end)    /* get to next char after * */
  298.         fill_buffer();
  299.  
  300.         if (unix_comment == 0)    /* set flag to show we are not in
  301.                      * unix-style comment */
  302.         unix_comment = 1;
  303.  
  304.         if (*buf_ptr == '/') {    /* it is the end!!! */
  305.     end_of_comment:
  306.         if (++buf_ptr >= buf_end)
  307.             fill_buffer();
  308.  
  309.         if (*(e_com - 1) != ' ' && !parser_state_tos->box_com) {    /* insure blank before
  310.                                  * end */
  311.             *e_com++ = ' ';
  312.             ++now_col;
  313.         }
  314.         if (break_delim == 1 && !one_liner && s_com[0] == '/'
  315.             && s_com[1] == '*' && s_com[2] == ' ') {
  316.             char       *t = e_com;
  317.             break_delim = 2;
  318.             e_com = s_com + 2;
  319.             *e_com = 0;
  320.             if (blanklines_before_blockcomments)
  321.             prefix_blankline_requested = 1;
  322.             dump_line();
  323.             e_com = t;
  324.             s_com[0] = s_com[1] = s_com[2] = ' ';
  325.         }
  326.         if (break_delim == 2 && e_com > s_com + 3
  327.              /* now_col > adj_max_col - 2 && !parser_state_tos->box_com */ ) {
  328.             *e_com = '\0';
  329.             dump_line();
  330.             now_col = parser_state_tos->com_col;
  331.         }
  332.         check_com_size;
  333.         *e_com++ = '*';
  334.         *e_com++ = '/';
  335.         *e_com = '\0';
  336.         parser_state_tos->just_saw_decl = l_just_saw_decl;
  337.         return;
  338.         }
  339.         else {        /* handle isolated '*' */
  340.         *e_com++ = '*';
  341.         ++now_col;
  342.         }
  343.         break;
  344.     default:        /* we have a random char */
  345.         if (unix_comment == 0 && *buf_ptr != ' ' && *buf_ptr != '\t')
  346.         unix_comment = 1;    /* we are not in unix-style comment */
  347.  
  348.         *e_com = *buf_ptr++;
  349.         if (buf_ptr >= buf_end)
  350.         fill_buffer();
  351.  
  352.         if (*e_com == '\t')    /* keep track of column */
  353.         now_col = ((now_col - 1) & tabmask) + tabsize + 1;
  354.         else if (*e_com == '\b')    /* this is a backspace */
  355.         --now_col;
  356.         else
  357.         ++now_col;
  358.  
  359.         if (*e_com == ' ' || *e_com == '\t')
  360.         last_bl = e_com;
  361.         /* remember we saw a blank */
  362.  
  363.         ++e_com;
  364.         if (now_col > adj_max_col && !parser_state_tos->box_com && unix_comment == 1 && e_com[-1] > ' ') {
  365.         /*
  366.          * the comment is too long, it must be broken up
  367.          */
  368.         if (break_delim == 1 && s_com[0] == '/'
  369.             && s_com[1] == '*' && s_com[2] == ' ') {
  370.             char       *t = e_com;
  371.             break_delim = 2;
  372.             e_com = s_com + 2;
  373.             *e_com = 0;
  374.             if (blanklines_before_blockcomments)
  375.             prefix_blankline_requested = 1;
  376.             dump_line();
  377.             e_com = t;
  378.             s_com[0] = s_com[1] = s_com[2] = ' ';
  379.         }
  380.         if (last_bl == 0) {    /* we have seen no blanks */
  381.             last_bl = e_com;    /* fake it */
  382.             *e_com++ = ' ';
  383.         }
  384.         *e_com = '\0';    /* print what we have */
  385.         *last_bl = '\0';
  386.         while (last_bl > s_com && last_bl[-1] < 040)
  387.             *--last_bl = 0;
  388.         e_com = last_bl;
  389.         dump_line();
  390.  
  391.         *e_com++ = ' ';    /* add blanks for continuation */
  392.         *e_com++ = ' ';
  393.         *e_com++ = ' ';
  394.  
  395.         t_ptr = last_bl + 1;
  396.         last_bl = 0;
  397.         if (t_ptr >= e_com) {
  398.             while (*t_ptr == ' ' || *t_ptr == '\t')
  399.             t_ptr++;
  400.             while (*t_ptr != '\0') {    /* move unprinted part of
  401.                          * comment down in buffer */
  402.             if (*t_ptr == ' ' || *t_ptr == '\t')
  403.                 last_bl = e_com;
  404.             *e_com++ = *t_ptr++;
  405.             }
  406.         }
  407.         *e_com = '\0';
  408.         now_col = count_spaces(parser_state_tos->com_col, s_com);    /* recompute current
  409.                                  * position */
  410.         }
  411.         break;
  412.     }
  413.     }
  414. }
  415.